package main

import (
	"fmt"
	"net"
	"sync"
)

type Server struct {
	Ip   string
	Port string

	MessageChan chan string // 消息通道

	UserMap     map[string]*User
	UserMapLock sync.RWMutex
}

func NewServer(ip, port string) *Server {
	server := &Server{
		Ip:          ip,
		Port:        port,
		MessageChan: make(chan string),
		UserMap:     make(map[string]*User),
	}

	return server
}

// 监听Server MessageChan
func (server *Server) MessageListener() {
	for {
		msg := <-server.MessageChan

		// 将消息发送给每一位在线的用户
		server.UserMapLock.Lock()
		for _, user := range server.UserMap {
			user.C <- msg
		}
		server.UserMapLock.Unlock()
	}
}

func (server *Server) BroadCast(user *User, msg string) {
	// 构建消息
	msg_info := fmt.Sprintf("[%s]%s:%s\n", user.Addr, user.Name, msg)

	server.MessageChan <- msg_info
}

func (server *Server) Handler(conn net.Conn) {
	// 这个方法在用户与服务器连接成功后触发

	// 创建用户
	user := NewUser(conn, server)

	// 将用户加入UserMap，多线程上锁
	server.UserMapLock.Lock()
	server.UserMap[user.Name] = user
	server.UserMapLock.Unlock()

	// 将用户上线信息发送到MessageChan
	user.Online()

	go user.ReadListener()

	go user.IsLiveListener()
}

// 启动一个TCP监听服务
func (server *Server) Start() {
	listener, err := net.Listen("tcp4", fmt.Sprintf("%s:%s", server.Ip, server.Port))

	if err != nil {
		fmt.Println("Server Start err: ", err)
	}

	// 结束之后关闭
	defer listener.Close()

	go server.MessageListener()

	fmt.Printf("Server Addr: http://%s:%s\n", server.Ip, server.Port)
	fmt.Println("Server Started, Wait Client Connect ...")

	for {
		// accept 阻塞，直到有连接
		conn, err := listener.Accept()

		if err != nil {
			fmt.Println("Server Connect err: ", err)
		}

		// 开启gorountine去处理这个连接
		go server.Handler(conn)
	}
}
